using MaterialSkin;
using MaterialSkin.Controls;
using SortGUI;
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.IO.Ports;
using System.Linq;
using System.Runtime.Serialization.Formatters;
using System.Text;
using System.Threading.Tasks;
using System.Timers;
using System.Windows.Forms;
using static SortGUI.SortBase;
using static System.Windows.Forms.VisualStyles.VisualStyleElement;

namespace SortGUI
{
    public partial class Form1 : MaterialForm
    {

        public SortBase currentSort;//当前排序算法
        int totalNum = 0;//数字总个数
        internal int interval = 2;//默认动画速
        internal int[] alNum;
        internal int speed = 0;
        internal int[] lastSwappedIndices = new int[2];
        internal int lastSortedIndex = -1;
        internal bool isSorting = false;
        internal bool swapped = false;
        internal bool isInitialize = true;
        internal bool isComplete = false;
        internal bool shouldStop = false;
        internal bool showImg = false;
        internal bool useGradientBrush=false;//是否使用渐变色
        private Image buttonImage1; // 储存原始图片
        private Image buttonImage2; // 储存点击后要切换的图片
        private Image bgImg;
        private readonly MaterialSkinManager materialSkinManager;
        private Brush currentBrush;
        private Brush tempBrush =Brushes.Blue;
        System.Threading.Thread t;
        //初始化界面
        public Form1()
        {
            materialSkinManager = MaterialSkinManager.Instance;
            materialSkinManager.Theme = MaterialSkinManager.Themes.LIGHT;
            materialSkinManager.ColorScheme = new ColorScheme(
            ColorTranslator.FromHtml("#455A64"),
            ColorTranslator.FromHtml("#263238"),
            ColorTranslator.FromHtml("#90A4AE"),
            ColorTranslator.FromHtml("#80D8FF"),
            TextShade.WHITE);
            Refresh();
            InitializeComponent();
            WeatherService ws = new WeatherService();
            nameBox.Text = "淮南";
            ws.WeatherReporter(nameBox.Text.Trim(), weatherpbView, weatherLabel);//初始化天气
            currentSort = new BubbleSort(); // 默认使用 Bubble Sort 
            alNum = new int[3];
            buttonImage1 = Properties.Resources.start; // 图片1的资源
            buttonImage2 = Properties.Resources.stop; // 图片2的资源
            btnStart.Image = buttonImage1;
            TransparencyKey = BackColor;
            BackColor = Color.Fuchsia;
        }
        private void Form1_SizeChanged(object sender, EventArgs e)
        {
            pbView.Invalidate();
        }
        //开始按钮事件
        private void btnStart_Click(object sender, EventArgs e)
        {
            btnStart.Enabled = true;
            tbTireCount.Enabled = false;
            btnRandom.Enabled = false;
            isSorting = false;
            shouldStop = false;
            System.Windows.Forms.ToolTip p = new System.Windows.Forms.ToolTip();
            p.ShowAlways = true;
            ActiveControl = null;
            if (btnStart.Image == buttonImage1) 
            {
                p.SetToolTip(btnStart, "中止");
                btnStart.Image = buttonImage2;
                totalNum = tbTireCount.Value;//排序元素个数等于滑块所指值
                label3.Text = "步数";
                pbView.Invalidate();
                Application.DoEvents();//挂起系统消息确保这次重绘立即发生
                System.Threading.Thread.Sleep(20);
                t = new System.Threading.Thread(new System.Threading.ThreadStart(Start));
                t.IsBackground = true;
                t.Start();
            }
            else
            {
                p.SetToolTip(btnStart, "开始");
                shouldStop = true;
                btnStart.Image = buttonImage1;
                btnRandom.Enabled = true;
            }
        }
        /// <summary>
        /// 1.btStart触发BubbleSort排序，开个线程
        /// 2.BubbleSort里调用绘图方法重绘界面
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        //绘制区域
        private void pictureBox1_Paint(object sender, PaintEventArgs e)
        {
            lableName.Parent = pbView;
            var g = e.Graphics;
            float boxWidth = pbView.Width;//绘图区宽度
            float boxHeight = pbView.Height;//绘图区高度
            int numCount = totalNum;//元素个数
            float numWidthes = (boxWidth / totalNum);//每个元素宽度
            float[] numHeights = new float[numCount];//每个元素的长度
            //生成每个柱子的高
            for (int i = 0; i < numHeights.Length; i++)
                numHeights[i] = boxHeight * 0.018f * alNum[i] * 0.18f;
            float bx = 0;
            float by = 0;
            g.DrawRectangle(Pens.DarkGray, bx, by, boxWidth, boxHeight);
            g.FillRectangle(Brushes.LightGray, bx, by, boxWidth, boxHeight);
            if (bgImg != null&&showImg)
                e.Graphics.DrawImage(bgImg, 0, 0, pbView.Width, pbView.Height);
            //每个矩形绘制起始坐标
            for (int numId = 0; numId < numCount; numId++)
            {
                Brush currentBrush = ChooseColor(numId);
                float xi = bx + numWidthes * numId;
                float rectBottom = by + boxHeight;
                float yi = rectBottom - numHeights[numId];
                g.FillRectangle(currentBrush, xi, yi, numWidthes, numHeights[numId]);
                g.DrawRectangle(Pens.Black, xi, yi, numWidthes, numHeights[numId]);
            }

            // 清除上次交换的索引记录，以便下一次循环
            Array.Clear(lastSwappedIndices, 0, lastSwappedIndices.Length);
        }
        private void Start()
        {
            isSorting = true;
            currentSort.updateUiCallback = UpdateUI;
            currentSort.updataColor = UpdataColor;
            currentSort.Sort(alNum);
            btnStart.Enabled = true;
            tbTireCount.Enabled = true;
            btnRandom.Enabled = true;
            btnStart.Image = buttonImage1;
            pbView.Invalidate();
            if (!shouldStop)
                MessageBox.Show("完成排序", "完成", MessageBoxButtons.OK, MessageBoxIcon.Information);
        }

        #region 选择算法
        private void cmbAlgorithms_Changed(object sender, EventArgs e)
        {
            switch (cmbSortAlgorithms.SelectedItem.ToString())
            {
                case "BubbleSort":
                    currentSort = new BubbleSort();
                    lableName.Text = "BubbleSort";
                    menu1pbView.Image = Image.FromFile(@"Resources\Picture\AlgorithmCpp\BubbleCpp.png");
                    menu2pbView.Image = Image.FromFile(@"Resources\Picture\AlgorithmCSharp\BubbleCSharp.png");
                    menu3pbView.Image = Image.FromFile(@"Resources\Picture\Complex\BubbleComplex.png");
                    break;
                case "QuickSort":
                    currentSort = new QuickSort();
                    lableName.Text = "QuickSort";
                    menu1pbView.Image = Image.FromFile(@"Resources\Picture\AlgorithmCpp\QuickCpp.png");
                    menu2pbView.Image = Image.FromFile(@"Resources\Picture\AlgorithmCSharp\QuickCSharp.png");
                    menu3pbView.Image = Image.FromFile(@"Resources\Picture\Complex\QuickComplex.png");
                    break;
                case "InsertSort":
                    currentSort = new InsertSort();
                    lableName.Text = "InsertSort";
                    menu1pbView.Image = Image.FromFile(@"Resources\Picture\AlgorithmCpp\InsertCpp.png");
                    menu2pbView.Image = Image.FromFile(@"Resources\Picture\AlgorithmCSharp\InsertCSharp.png");
                    menu3pbView.Image = Image.FromFile(@"Resources\Picture\Complex\InsertComplex.png");
                    break;
                case "SelectSort":
                    currentSort = new SelectSort();
                    lableName.Text = "SelectSort";
                    menu1pbView.Image = Image.FromFile(@"Resources\Picture\AlgorithmCpp\SelectCpp.png");
                    menu2pbView.Image = Image.FromFile(@"Resources\Picture\AlgorithmCSharp\SelectCSharp.png");
                    menu3pbView.Image = Image.FromFile(@"Resources\Picture\Complex\SelectComplex.png");
                    break;
                case "MergeSort":
                    currentSort = new MergeSort();
                    lableName.Text = "MergeSort";
                    menu1pbView.Image = Image.FromFile(@"Resources\Picture\AlgorithmCpp\MergeCpp.png");
                    menu2pbView.Image = Image.FromFile(@"Resources\Picture\AlgorithmCSharp\MergeCSharp.png");
                    menu3pbView.Image = Image.FromFile(@"Resources\Picture\Complex\MergeComplex.png");
                    break;
                case "ShellSort":
                    currentSort = new ShellSort();
                    lableName.Text = "ShellSort";
                    menu1pbView.Image = Image.FromFile(@"Resources\Picture\AlgorithmCpp\ShellCpp.png");
                    menu2pbView.Image = Image.FromFile(@"Resources\Picture\AlgorithmCSharp\ShellCSharp.png");
                    menu3pbView.Image = Image.FromFile(@"Resources\Picture\Complex\ShellComplex.png");
                    break;
                case "OddEvenSort":
                    currentSort = new OddEvenSort();
                    lableName.Text = "OddEvenSort";
                    menu1pbView.Image = Image.FromFile(@"Resources\Picture\AlgorithmCpp\OddEvenCpp.png");
                    menu2pbView.Image = Image.FromFile(@"Resources\Picture\AlgorithmCSharp\OddEvenCSharp.png");
                    menu3pbView.Image = Image.FromFile(@"Resources\Picture\Complex\OddEvenComplex.png");
                    break;
                    // ... 添加其他算法的创建逻辑
            }
            ActiveControl = null;//将焦点转移到窗体上
        }
        #endregion

        #region 回调函数用于排序后更新界面
        private void UpdateUI(int count, int[] lastSwappedIndices, int lastSortedIndex, bool swapped)
        {
            if (!shouldStop)
            {
                pbView.Invalidate();
                label1.Text = count.ToString();
                this.lastSwappedIndices = lastSwappedIndices; // 更新全局变量
                this.lastSortedIndex = lastSortedIndex;
                this.swapped = swapped;
                System.Threading.Thread.Sleep(interval);
            }
            else
                        pbView.Invalidate();
        }
        #endregion
        //颜色更新
        private void UpdataColor(bool isInitialize)
        {
            if (!shouldStop)
                this.isInitialize = isInitialize;
        }


        #region 选择颜色
           
        private Brush ChooseColor(int numId)
        {
            currentBrush = tempBrush;
            bool isSwapped = false;
            // 定义渐变色刷子
            Rectangle rect = new Rectangle((int)(   pbView.Width * numId / totalNum), 0, (int)(pbView.Width / totalNum), pbView.Height);

            foreach (var index in lastSwappedIndices)//看numId是否在交换列表中，如果是则将交换置为true
            {
                if (index == numId)
                {
                    isSwapped = true;
                    break;
                }
            }

            if (isSorting && numId >= lastSortedIndex && !isInitialize)//排序完成颜色
            {
                return useGradientBrush
                    ? new LinearGradientBrush(rect, Color.LightGreen, Color.DarkGreen, LinearGradientMode.Vertical)
                    : Brushes.Green;
            }
            else if (isSwapped && !isInitialize)//交换颜色
            {
                return useGradientBrush
                    ? new LinearGradientBrush(rect, Color.Yellow, Color.OrangeRed, LinearGradientMode.Vertical)
                    : Brushes.Yellow;
            }
            else//初始颜色
            {
                return useGradientBrush
                    ? new LinearGradientBrush(rect, Color.Black, Color.LightGray, LinearGradientMode.Vertical)
                    : tempBrush;
            }
            
        }
        #endregion

        #region 主题按钮
        private void btnRandom_Click(object sender, EventArgs e)
        {
            shouldStop = false;
            isSorting = false;
            isInitialize = true;
            ArrayMaker.randomArray(ref alNum, totalNum);
            ActiveControl = null;
            pbView.Invalidate();
        }
        private void rbLightTheme_CheckedChanged(object sender, EventArgs e)
        {
            materialSkinManager.Theme = MaterialSkinManager.Themes.LIGHT;
            materialSkinManager.ColorScheme = new ColorScheme(
            ColorTranslator.FromHtml("#CACDCC"),
            ColorTranslator.FromHtml("#BABDBC"),
            ColorTranslator.FromHtml("#D8DBE2"),
            ColorTranslator.FromHtml("#96959B"),
            TextShade.BLACK);
            Refresh();
        }

        private void rbGreenTheme_CheckedChanged(object sender, EventArgs e)
        {
            materialSkinManager.Theme = MaterialSkinManager.Themes.LIGHT;
            materialSkinManager.ColorScheme = new ColorScheme(
                ColorTranslator.FromHtml("#009688"), 
                ColorTranslator.FromHtml("#00796B"), 
                ColorTranslator.FromHtml("#66BB6A"), 
                ColorTranslator.FromHtml("#FFCDD2"), 
                TextShade.BLACK);
            Refresh();
        }

        private void rbLovely_CheckedChanged(object sender, EventArgs e)
        {
            materialSkinManager.Theme = MaterialSkinManager.Themes.LIGHT;
            materialSkinManager.ColorScheme = new ColorScheme(
                ColorTranslator.FromHtml("#f09819"),
                ColorTranslator.FromHtml("#c07819"),
                ColorTranslator.FromHtml("#f09819"),
                ColorTranslator.FromHtml("#ff5858"),
                TextShade.WHITE);
            Refresh();
        }

        private void rbBatmanTheme_CheckedChanged(object sender, EventArgs e)
        {
            materialSkinManager.Theme = MaterialSkinManager.Themes.LIGHT;
            materialSkinManager.ColorScheme = new ColorScheme(
            ColorTranslator.FromHtml("#455A64"),
            ColorTranslator.FromHtml("#263238"),
            ColorTranslator.FromHtml("#90A4AE"),
            ColorTranslator.FromHtml("#80D8FF"),
            TextShade.WHITE);
            Refresh();
        }
        #endregion

        //透明度滑块
        #region 个数滑块
        private void tbTireCountMS_MouseMove(object sender, MouseEventArgs e)
        {
            shouldStop = false;
            ActiveControl = null;
            totalNum = tbTireCount.Value;
            alNum = new int[totalNum];
            ArrayMaker.initArray(ref alNum, totalNum);
            pbView.Invalidate();
        }
        private void tbTireCount_MouseClick(object sender, MouseEventArgs e)
        {
            label1.Text = "0";
            isSorting = false;
            isInitialize = true;
        }
#endregion
        private void transparencySlider_MouseMove(object sender, MouseEventArgs e)
        {
            Opacity = (100 - transparencySlider.Value) * 0.01;
        }

        //速度滑块
        private void tbSpeedMS_MouseMove(object sender, MouseEventArgs e)
        {
            speed = tbSpeed.Value;
            interval = 1 << speed;
            ActiveControl = null;
        }


        #region 柱子颜色
        //印度红
        private void rdRedPillar_CheckedChanged(object sender, EventArgs e)
        {
            tempBrush=Brushes.IndianRed;
            useGradientBrush = false;
        }

        //默认色
        private void rbBulePillar_CheckedChanged(object sender, EventArgs e)
        {
            tempBrush = Brushes.Blue;
            useGradientBrush = false;
        }
        //渐变色
        private void rbGray_CheckedChanged(object sender, EventArgs e)
        {
            useGradientBrush = true;
        }

        #endregion

        private void noImg_CheckedChanged(object sender, EventArgs e)
        {
            showImg = false;
        }

        private void showImgs_CheckedChanged(object sender, EventArgs e)
        {
            bgImg = Properties.Resources.c;
            showImg =true;
        }

        private void bgAsuka_CheckedChanged(object sender, EventArgs e)
        {
            bgImg= Properties.Resources.asuka;
            showImg = true;
        }

        private void btnWeather_Click(object sender, EventArgs e)
        {
            WeatherService ws = new WeatherService();
            ws.WeatherReporter(nameBox.Text.Trim(), weatherpbView, weatherLabel);
            weatherpbView.Invalidate();
        }

        private void weatherSwitch_CheckedChanged(object sender, EventArgs e)
        {
            weatherLabel.Visible = weatherSwitch.Checked;
            weatherpbView.Visible = weatherSwitch.Checked;  
        }

        private void siderBarSwitch_CheckedChanged(object sender, EventArgs e)
        {
            splitContainer1.Panel1Collapsed=siderBarSwitch.Checked;
        }
        //快捷键
        private void Form1_KeyDown(object sender, KeyEventArgs e)
        {
            switch (e.KeyCode)
            {
                case Keys.H://hide sideBar
                    if (e.KeyCode == Keys.H && siderBarSwitch.Checked == false)
                    {
                        siderBarSwitch.Checked = true;
                        e.Handled = true;
                    }
                    else
                    {
                        siderBarSwitch.Checked = false;
                        e.Handled = true;
                    }
                    break;
                case Keys.S://Sort Start
                    btnStart_Click(sender, e);
                    break;
                case Keys.R://Random
                    btnRandom_Click(sender, e);
                    break;
            }
        }
    }
}
